package ru.vms.healthcontrol;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpException;

import loc.org.json.JSONException;
import loc.org.json.JSONObject;

import android.accounts.NetworkErrorException;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import pro.notum.interfaces.IModel;
import pro.notum.interfaces.IPresenter;
import pro.notum.interfaces.IRequestCompleteObserver;
import pro.notum.interfaces.IRequestExecutorSubject;
import ru.vms.healthcontrol.RequestResult.Predefined;


public class NotumModel implements IModel, IRequestExecutorSubject {

	Activity activ = null;
	IPresenter presenter  = null;
	UserData user_data = null;
	private DBProvider dbProvider;
	private RequestResult lastRequestResult;
	private List<IRequestCompleteObserver> observers = new LinkedList<IRequestCompleteObserver>();
	
	private AsyncTask<Void , Void, Void> uiTask = null;
	
	public NotumModel ( IPresenter p ) {
		this.presenter = p;
		activ = p.getActivity();
		user_data = UserData.getDefault();
		this.dbProvider = new DBProvider(activ.getApplicationContext());
		registerReqCompleteObserver(this.presenter);
	}


	public void userPreferencesChanged() {
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(activ);
		user_data = UserData.loadCurrentUserData(sp);		
	}


	public UserData getUserData() {
		return user_data;
	}


	public boolean isExistValuesForDate(Date d) {
		return dbProvider.rowsByDate(d) > 0;
	}

	

	public void insert(ValueUnderControl value) {
		dbProvider.insert(value);
	}


	public void selectAllLog() {
		dbProvider.selectAll();
		
	}


	public void update(ValueUnderControl value) {
		dbProvider.update(value);		
	}

	public void signOutNotumPro() {
		this.setAuthorizationStatus(false);
		this.userPreferencesChanged();
	}

	public boolean signInNotumPro() {
		
		if( uiTask != null && uiTask.getStatus() != AsyncTask.Status.FINISHED )
			return false;
		
		final GatewayUtil gateway = new GatewayUtil(activ.getApplicationContext());
		
		
		uiTask = new AsyncTask<Void, Void, Void> () {
			private RequestResult lastRequestResult;
			private String v_coaccount = "";
			private String v_conickname = "";
			private String v_sid = "";

			@Override
			protected Void doInBackground(Void... params) {
				
				try {
					
					this.lastRequestResult = gateway.authorization(getUserData());
					
					JSONObject v = this.lastRequestResult.getValues();
					
					this.v_conickname = v.isNull("v_conickname")? "" : v.getString("v_conickname");
					this.v_coaccount = v.isNull("v_coaccount")? "" : v.getString("v_coaccount");
					this.v_sid = v.isNull("v_sid")? "" :  v.getString("v_sid");
					// not need for first authorization in UI
					
					
					
				} catch (JSONException e) {
					NetLog.e("%s", e.toString());
					e.printStackTrace();
					this.lastRequestResult = RequestResult.createPredefinedResult(Predefined.INVALID_SERVER_ANSEWER, NotumModel.this.activ);
					
				} catch ( NetworkErrorException e ) {
					NetLog.e("%s", e.toString());
					e.printStackTrace();
					this.lastRequestResult = RequestResult.createPredefinedResult(Predefined.INVALID_CONNECTION, NotumModel.this.activ);
					
				} catch ( Exception e ) {
					NetLog.e("%s", e.toString());
					e.printStackTrace();
					this.lastRequestResult = RequestResult.createPredefinedResult(Predefined.UNDEFINED_ERROR, NotumModel.this.activ);
				}
				
				return null;
			}
			
			@Override
			protected void onPostExecute(Void result) {
				super.onPostExecute(result);
				NotumModel.this.lastRequestResult = this.lastRequestResult;
				
				if( lastRequestResult.getResult() >= 0 && lastRequestResult.isSucceess() && v_sid.length() > 0 ) {
					
					NotumModel.this.setAuthorizationStatus(true);
					NotumModel.this.userPreferencesChanged();
				}
				
				notifyReqCompleteObservers();
			}
		};
		
		uiTask.execute();
		
		return true;
	}


	protected void setAuthorizationStatus(boolean b) {
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(activ);
		SharedPreferences.Editor edit = sp.edit();
		edit.putBoolean("signin_complete", b);
		edit.commit();
	}


	public RequestResult getLastRequestResult() {
		return lastRequestResult;
	}


	public void registerReqCompleteObserver(IRequestCompleteObserver obs) {
		this.observers.add(obs);
		
	}


	public void removeReqCompleteObserver(IRequestCompleteObserver obs) {
		int i = observers.indexOf(obs);
		if( i >= 0 )
			observers.remove(i);
		else 
			NetLog.v("Try remove undefined observer");
		
	}


	public void notifyReqCompleteObservers() {
		for (IRequestCompleteObserver cur : observers) {
			cur.requestComplete();
		}
		
	}


	
	public List<ValueUnderControl> selectByName(String name) {
		return dbProvider.selectByName(name);
	}
	
	
}
